package com.huawei.opengl_isrc.slice;

import android.opengl.GLES10;
import com.huawei.opengl_isrc.ResourceTable;
import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.content.Intent;
import ohos.agp.components.Component;
import ohos.agp.components.DirectionalLayout;
import ohos.agp.render.opengl.EGLConfig;
import ohos.agp.render.opengl.GLES1X;
import ohos.app.Context;
import ohos.opengl.GLSurfaceProvider;
import ohos.opengl.GLU;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;

public class GLSurfaceProviderSlice extends AbilitySlice {
    /**
     * @Author: DY
     * @Date: 2020/12/31
     */

    @Override
    public void onStart(Intent intent) {
        super.onStart(intent);
        super.setUIContent(ResourceTable.Layout_Demo_SurfaceProvider);
        DirectionalLayout myLayout = (DirectionalLayout) findComponentById(ResourceTable.Id_GLSurfaceProvider);
        GlSurfaceProvider glSurfaceProvider = new GlSurfaceProvider(this);
        glSurfaceProvider.pinToZTop(true);
        myLayout.addComponent(glSurfaceProvider);

        //返回按钮
        findComponentById(ResourceTable.Id_tab_back).setClickedListener(new Component.ClickedListener() {
            @Override
            public void onClick(Component component) {
                Intent secondIntent = new Intent();
                secondIntent.setOperation(new Intent.OperationBuilder()
                        .withBundleName("com.huawei.opengl_isrc")
                        .withAbilityName("com.huawei.opengl_isrc.MainAbility")
                        .build());
                startAbility(secondIntent);
            }
        });

    }
    //创建GLSurfaceProvider
    public class GlSurfaceProvider extends GLSurfaceProvider {
        public GlSurfaceProvider(Context context) {
            super(context);
            //更改注释来选择Renderer
//            setRenderer(new GlRenderer());
//            setRenderer(new OpenGlTest());
            setRenderer(new SecondActivity());
        }
    }
    //三角形旋转Renderer
    public class OpenGlTest implements GLSurfaceProvider.Renderer{
        GLES10 gl2=new GLES10();
        float rotateTri,rotateQuad;
        int one=0x10000;
        private IntBuffer triggerBuffer=BufferUtil.fBuffer(new int[]{
                0,one,0,     //上顶点
                -one,-one,0,    //左顶点
                one,-one,0    //右下点
        });
        private IntBuffer quateBuffer=BufferUtil.fBuffer(new int[]{
                one,one,0,
                -one,-one,0,
                one,-one,0,
                -one,-one,0
        });
        private IntBuffer colorBuffer=BufferUtil.fBuffer(new int[]{
                one,0,0,one,
                0,one,0,one,
                0,0,one,one
        });

        @Override
        public void onDrawFrame(GLES1X gl) {
            // 清除屏幕和深度缓存
            gl2.glClear(gl2.GL_COLOR_BUFFER_BIT | gl2.GL_DEPTH_BUFFER_BIT);
            // 重置当前的模型观察矩阵
            gl2.glLoadIdentity();
            // 左移 1.5 单位，并移入屏幕 6.0
            gl2.glTranslatef(-1.5f, 0.0f, -6.0f);
            //设置旋转
            gl2.glRotatef(rotateTri, 0.0f, 1.0f, 0.0f);
            //设置定点数组
            gl2.glEnableClientState(gl2.GL_VERTEX_ARRAY);
            //设置颜色数组
            gl2.glEnableClientState(gl2.GL_COLOR_ARRAY);
            gl2.glColorPointer(4, gl2.GL_FIXED, 0, colorBuffer);
            // 设置三角形顶点
            gl2.glVertexPointer(3, gl2.GL_FIXED, 0, triggerBuffer);
            //绘制三角形
            gl2.glDrawArrays(gl2.GL_TRIANGLES, 0, 3);

            gl2.glDisableClientState(gl2.GL_COLOR_ARRAY);
            //绘制三角形结束
            gl2.glFinish();
            /***********************/
            /* 渲染正方形 */
            // 重置当前的模型观察矩阵
            gl2.glLoadIdentity();

            // 左移 1.5 单位，并移入屏幕 6.0
            gl2.glTranslatef(1.5f, 0.0f, -6.0f);

            // 设置当前色为蓝色
            gl2.glColor4f(0.5f, 0.5f, 1.0f, 1.0f);
            //设置旋转
            gl2.glRotatef(rotateQuad, 1.0f, 0.0f, 0.0f);

            //设置和绘制正方形
            gl2.glVertexPointer(3, gl2.GL_FIXED, 0, quateBuffer);
            gl2.glDrawArrays(gl2.GL_TRIANGLE_STRIP, 0, 4);

            //绘制正方形结束
            gl2.glFinish();

            //取消顶点数组
            gl2.glDisableClientState(gl2.GL_VERTEX_ARRAY);
            //改变旋转的角度
//            rotateTri += 0.5f;
            rotateTri += 25f;
            rotateQuad -= 15f;

        }

        @Override
        public void onSurfaceChanged(GLES1X gl, int width, int height) {
            float ratio = (float) width / height;
            //设置OpenGL场景的大小
            gl2.glViewport(0, 0, width, height);
            //设置投影矩阵
            gl2.glMatrixMode(gl2.GL_PROJECTION);
            //重置投影矩阵
            gl2.glLoadIdentity();
            // 设置视口的大小
            gl2.glFrustumf(-ratio, ratio, -1, 1, 1, 10);
            // 选择模型观察矩阵
            gl2.glMatrixMode(gl2.GL_MODELVIEW);
            // 重置模型观察矩阵
            gl2.glLoadIdentity();
        }

        @Override
        public void onSurfaceCreated(GLES1X gl, EGLConfig arg1) {
            gl2.glShadeModel(gl2.GL_SMOOTH);
            // 黑色背景
            gl2.glClearColor(0, 0, 0, 0);
            // 设置深度缓存
            gl2.glClearDepthf(1.0f);
            // 启用深度测试
            gl2.glEnable(gl2.GL_DEPTH_TEST);
            // 所作深度测试的类型
            gl2.glDepthFunc(gl2.GL_LEQUAL);
            // 告诉系统对透视进行修正
            gl2.glHint(gl2.GL_PERSPECTIVE_CORRECTION_HINT, gl2.GL_FASTEST);
        }

    }
    //立体旋转Renderer
    public class SecondActivity implements GLSurfaceProvider.Renderer {
        GLES10 gl2 = new GLES10();
        private float[] mArray = new float[]{
                0.0f,0.5f,0.0f,
                -0.5f,-0.5f,-0.2f,
                0.5f,0.5f,-0.2f,
                0.0f,-0.6f,0.2f,
        };
        int[] colors = new int[]{
                65535,0,0,0,    //红
                0,65535,0,0,    //绿
                0,0,65535,0,    //蓝
                0,65535,65535,0,    //蓝
        };
        ByteBuffer taperFacets=ByteBuffer.wrap(
                new byte[]{
                        0,1,2,
                        0,1,3,
                        1,2,3,
                        0,2,3,
                }
        );

        public float b=45;
        public void onSurfaceCreated(GLES1X gl, EGLConfig config) {
            gl2.glClearColor(0,0,0,0); //背景色
            gl2.glShadeModel(GLES10.GL_SMOOTH);    //打开平滑着色模式
            //gl.glTranslatef(0.6f,0f,0f);  //平移
            gl2.glEnable(GLES10.GL_DEPTH_TEST);    //启用Z轴,启动3D
            gl2.glDepthFunc(GLES10.GL_LEQUAL); //被遮挡的颜色要被显示出来
        }

        public void onSurfaceChanged(GLES1X gl, int width, int height) {
            gl2.glViewport(0,0,width,height);//起始坐标
            gl2.glMatrixMode(GLES10.GL_PROJECTION); //正交投影
            gl2.glLoadIdentity();//初始化单位矩阵
            //设置宽高比
            float a = (float)width/height;
            gl2.glFrustumf(-a,a,-1,1,1f,1000f);   //设置透视投影的大小
        }

        public void onDrawFrame(GLES1X gl) {
            gl2.glClear(GLES10.GL_COLOR_BUFFER_BIT);//清理缓冲区，并设置为预设值
            gl2.glClear(GLES10.GL_DEPTH_BUFFER_BIT);//清除深度缓冲区

            gl2.glEnableClientState(GLES10.GL_VERTEX_ARRAY);//允许顶点数组
            gl2.glEnableClientState(GLES10.GL_COLOR_ARRAY);//启用颜色矩阵

            gl2.glMatrixMode(GLES10.GL_MODELVIEW); //物体变化前提
            gl2.glLoadIdentity();

            gl2.glTranslatef(0f,0f,-2.0f);   //平移,远离我们
            gl2.glRotatef(b,-0.1f,-0.1f,0.0f);

            gl2.glVertexPointer(3,GLES10.GL_FLOAT,0,BufferUtil.floatBufferUtil(mArray));     //设置
            gl2.glColorPointer(4,GLES10.GL_FIXED,0,BufferUtil.fBuffer(colors));

            gl2.glDrawElements(GLES10.GL_TRIANGLE_STRIP,taperFacets.remaining(),
                    GLES10.GL_UNSIGNED_BYTE,taperFacets);        //画图模式、数组名、

            gl2.glDisableClientState(GLES10.GL_VERTEX_ARRAY);//停止
            b+=10;
        }
    }
    //红色三角形Renderer
    public class GlRenderer implements GLSurfaceProvider.Renderer {
        //参考https://blog.csdn.net/gigi_/article/details/53558906
        //创建GLES10
        GLES10 gl2 = new GLES10();

        @Override
        public void onSurfaceCreated(GLES1X gl, EGLConfig config) {

            //设置背景色,透明度1为完全不透明
            gl2.glClearColor(0f, 0, 0f, 1f);
            //启用客户端状态,启用顶点缓冲区
            gl2.glEnableClientState(GLES10.GL_VERTEX_ARRAY);
        }

        //表层size改变时，即画面的大小改变时调用
        @Override
        public void onSurfaceChanged(GLES1X gl, int width, int height) {
            //设置视口,输出画面的区域,在控件的什么区域来输出,x,y是左下角坐标
            gl2.glViewport(0, 0, width, height);
            float ratio =(float) width /(float) height;

            //矩阵模式,投影矩阵,openGL基于状态机
            gl2.glMatrixMode(GLES10.GL_PROJECTION);
            //加载单位矩阵
            gl2.glLoadIdentity();
            //平截头体
            gl2.glFrustumf(-1f, 1f, -ratio, ratio, 3, 7);
        }

        //绘图
        @Override
        public void onDrawFrame(GLES1X gl) {
            //清除颜色缓冲区
            gl2.glClear(gl2.GL_COLOR_BUFFER_BIT);
            //模型视图矩阵
            gl2.glMatrixMode(GLES10.GL_MODELVIEW);
            //操作新矩阵要先清0,加载单位矩阵
            gl2.glLoadIdentity();
            //眼睛放的位置,eyes,eyey,eyez眼球(相机)的坐标
            //centerx,y,z镜头朝向，眼球的观察点
            //upx,upy,upz:指定眼球向上的向量,眼睛正着看
            GLU.gluLookAt(gl2, 0, 0, 5, 0, 0, 0,
                    0,1,0);
            //画三角形
            //三角形的坐标
            float[] coords = {
                    0f,0.5f,0f,
                    -0.5f,-0.5f,1f,
                    0.5f,-0.5f,0f,
            };
            //分配字节缓冲区空间,存放顶点坐标数据,将坐标放在缓冲区中
            ByteBuffer ibb = ByteBuffer.allocateDirect(coords.length * 4);  //直接分配字节的大小
            //设置顺序(本地顺序)
            ibb.order(ByteOrder.nativeOrder());
            //放置顶点坐标数组
            FloatBuffer fbb =  ibb.asFloatBuffer();
            fbb.put(coords);
            //定位指针的位置,从该位置开始读取顶点数据
            ibb.position(0);
            //设置绘图的颜色，红色
            gl2.glColor4f(1f, 0f, 0f, 1f);
            //3:3维点,使用三个坐标值表示一个点
            //type:每个点的数据类型
            //stride:0,上,点的跨度
            //ibb:指定顶点缓冲区
            gl2.glVertexPointer(3, gl2.GL_FLOAT, 0, ibb);
            //绘制三角形数组
            gl2.glDrawArrays(gl2.GL_TRIANGLES, 0, 3);   //count以点的数量来算,为3
        }


    }


    @Override
    public void onActive() {
        super.onActive();
    }

    @Override
    public void onForeground(Intent intent) {
        super.onForeground(intent);
//        GLSurfaceProviderSlice.super.terminate();
    }


}
class BufferUtil {
    public static IntBuffer intBuffer;
    public static IntBuffer fBuffer(int[] a) {

        // 先初始化buffer,数组的长度*4,因为一个float占4个字节

        ByteBuffer mbb = ByteBuffer.allocateDirect(a.length * 4);

        // 数组排列用nativeOrder

        mbb.order(ByteOrder.nativeOrder());

        intBuffer = mbb.asIntBuffer();

        intBuffer.put(a);

        intBuffer.position(0);

        return intBuffer;

    }
    public static FloatBuffer mBuffer;
    public static FloatBuffer floatBufferUtil(float[] arr) {

        // 初始化ByteBuffer，长度为arr数组的长度*4，因为一个int占4个字节
        ByteBuffer qbb = ByteBuffer.allocateDirect(arr.length * 4);
        // 数组排列用nativeOrder
        qbb.order(ByteOrder.nativeOrder());
        mBuffer = qbb.asFloatBuffer();
        mBuffer.put(arr);
        mBuffer.position(0);
        return mBuffer;
    }


}